/*
 * FileComparisor.cpp
 *
 *  Created on: Aug 20, 2013
 *      Author: jeff
 */
#include <stdlib.h>
#include <sstream>
#include <hash/md5.h>
#include "RawFileComparisor.h"

namespace fs {

Json::Value RawFileComparisor::compare()
{
	MD5 md5;
	MD5 block_md5;

	char* buffer_left = new char[buffer_size];
	char* buffer_right = new char[buffer_size];

	int left_buffer_length= read_left(buffer_left, buffer_size);
	int right_buffer_length = read_right(buffer_right, buffer_size);

	md5.Init();
	while((0 != left_buffer_length) || (0 != right_buffer_length))
	{
		md5.Update((unsigned char*)buffer_left, left_buffer_length);
		/*if(0 < left_buffer_length)
		{
			block_md5.Init();
			block_md5.Update((unsigned char*)buffer_left, left_buffer_length);
			block_md5.Final();
			md5.Update((unsigned char *)block_md5.digestChars, 33);
		}
		block[JSON_KEY_HASH] = block_md5.digestChars;*/

		//Json::Value block;
		diff(buffer_left, left_buffer_length, buffer_right, right_buffer_length, /*&block*/&root);
		//(*root)[JSON_KEY_BLOCK].append(block);

		left_buffer_length = read_left(buffer_left, buffer_size);
		right_buffer_length = read_right(buffer_right, buffer_size);
	}

	std::string right_file;
	delete[] buffer_left;
	delete[] buffer_right;

	md5.Final();
	root[JSON_KEY_HASH] = md5.digestChars;

	close_left_input();
	close_right_input();
	close_segment_file();

	return root;
}

void RawFileComparisor::setLeft(std::string left)
{
	init_left_input(left);
	//root[JSON_KEY_LEFT_FILE] = left;
}

void RawFileComparisor::setRight(std::string right)
{
	init_right_input(right);

	right_filename = right;
	root[JSON_KEY_RIGHT_FILE] = right;
}

void RawFileComparisor::init_left_input(std::string left){
	fs_left.open(left.c_str(), std::fstream::in | std::ios::binary);
	cursor_left = fs_left.rdbuf();
	cursor_left->pubseekpos (0, std::ios::in);
}

void RawFileComparisor::init_right_input(std::string right){
	fs_right.open(right.c_str(), std::fstream::in | std::ios::binary);
	cursor_right = fs_right.rdbuf();
	cursor_right->pubseekpos (0, std::ios::in);
}

int RawFileComparisor::read_left(char * buffer, int length){
	return cursor_left->sgetn(buffer, length);
}

int RawFileComparisor::read_right(char * buffer, int length){
	return cursor_right->sgetn(buffer, length);
}

void RawFileComparisor::close_left_input(){
	fs_left.close();
}

void RawFileComparisor::close_right_input(){
	fs_right.close();
}

std::string RawFileComparisor::get_segment_filename(){
	segment_filename = right_filename + POST_FIX;
	return segment_filename;
}
void RawFileComparisor::open_segment_file(){
	if(!segment_file.is_open())
	{
		segment_file.open(get_segment_filename().c_str(), std::ios::out | std::ios::binary);
		root[JSON_KEY_SEGMENT_FILE] = segment_filename.c_str();
	}
}

void RawFileComparisor::close_segment_file(){
	if(segment_file.is_open())
	{
		segment_file.close();
	}
}

void RawFileComparisor::output_diff_data(int insert_length, const char * diff, Json::Value* segment)
{
	if(insert_length > 0)
	{
		open_segment_file();
		segment_file.write(diff, insert_length);
	}
}

}
